<?php
// +-------------------------------------------------------------------------------
// | DingZone [ A Rapid Development Framework For Dingtalk ]
// +-------------------------------------------------------------------------------
// | 拓展标签 v1.0
// |
// | Copyright (c) 2014-2018 http://www.heimalanshi.com All rights reserved.
// | Author : Jie
// | Date : 2018-08-09
// +-------------------------------------------------------------------------------

namespace taglib;

use ding\model\MediaTypeEnum;
use think\template\TagLib;

class D extends TagLib {
    // 标签定义
    protected $tags = [
        // 标签定义： attr 属性列表 close 是否闭合（0 或者1 默认1） alias 标签别名 level 嵌套层次
        'upload' => ['attr' => 'type,multi,result,callback,field,class,upload,value,id'],
        'up' => ['attr' => 'class,id,success,type,value,w,h,field,btn,maxsize,tip'],
        'cdu' => ['attr' => 'id,name,dept,user,role,dynamic,rootdept,value,multi'],
        'textarea' => ['attr' => 'id,name,class,value,impl,options'],
        'picker' => ['attr' => 'id,name,class,value,url,keyField,titleField,multi'],
        'geo' => ['attr' => 'id,name,class']
    ];

    /**
     * 获取标签属性值
     *
     * @param $tag
     * @param $attrName
     * @param string $defaultVal
     * @return string
     */
    private function getTagAttr($tag, $attrName, $defaultVal = '') {
        if ($tag && isset($tag[$attrName]) && !empty($tag[$attrName])) {
            return $tag[$attrName];
        }
        return $defaultVal;
    }

    /**
     * 解析json格式的属性值
     *
     * @param $attrStrVal
     * @return array|mixed
     */
    private function parseJsonAttr($attrStrVal) {
        if (empty($attrStrVal)) {
            return [];
        }
        //在模板中{和}会被解析，因此要使用其他字符替换
        $attrStrVal = str_replace("《", "{", $attrStrVal);
        $attrStrVal = str_replace("》", "}", $attrStrVal);
        return json_decode($attrStrVal, true);
    }

    /**
     * 地理坐标拾取
     *
     * @param $tag
     * @param $content
     * @return string
     */
    public function tagGeo($tag, $content) {
        $id = $this->getTagAttr($tag, 'id', '');
        $name = $this->getTagAttr($tag, 'name', '');
        $className = $this->getTagAttr($tag, 'class', '');

        $parseStr = "<?php \n";
        if (empty($id)) {
            $parseStr .= "$" . "__s_geo_id = 'geo_' . time() . \common\Random::get();\n";
        } else {
            $parseStr .= $this->_generatePhpDefinationBlock("__s_geo_id", $id);
        }
        $parseStr .= $this->_generatePhpDefinationBlock("__s_geo_class", $className);
        $parseStr .= $this->_generatePhpDefinationBlock("__s_geo_name", $name);
        $parseStr .= "$" . "__s_geo_hint = '" . $content . "';";
        $parseStr .= " ?>\n";
        $parseStr .= file_get_contents(__DIR__ . "/tpl/geo.php");

        return $parseStr . $content;
    }

    /**
     * picker组件
     *
     * @param $tag
     * @param $content
     * @return string
     */
    public function tagPicker($tag, $content) {
        $id = $this->getTagAttr($tag, 'id', '');
        $name = $this->getTagAttr($tag, 'name', '');
        $className = $this->getTagAttr($tag, 'class', '');
        $bean = $this->getTagAttr($tag, 'bean', '');
        $keyField = $this->getTagAttr($tag, 'keyField', 'id');
        $titleField = $this->getTagAttr($tag, 'titleField', 'title');
        $multi = $this->getTagAttr($tag, 'multi', true);
        if ($multi === 'false' || $multi === 0) {
            $multi = false;
        } else {
            $multi = true;
        }

        $parseStr = "<?php \n";
        if (empty($id)) {
            $parseStr .= "$" . "__s_picker_id = 'picker_' . time() . \common\Random::get();\n";
        } else {
            $parseStr .= $this->_generatePhpDefinationBlock("__s_picker_id", $id);
        }
        $parseStr .= $this->_generatePhpDefinationBlock("__s_picker_class", $className);
        $parseStr .= $this->_generatePhpDefinationBlock("__s_picker_name", $name);
        $parseStr .= $this->_generatePhpDefinationBlock("__s_picker_bean", $bean);
        $parseStr .= $this->_generatePhpDefinationBlock("__s_picker_keyField", $keyField);
        $parseStr .= $this->_generatePhpDefinationBlock("__s_picker_titleField", $titleField);
        $parseStr .= $this->_generatePhpDefinationBlock("__s_picker_multi", $multi);
        $parseStr .= "$" . "__s_picker_hint = '" . $content . "';";
        $parseStr .= " ?>\n";
        $parseStr .= file_get_contents(__DIR__ . "/tpl/picker.php");

        return $parseStr . $content;
    }

    /**
     * 富文本框
     *
     * @param $tag
     * @param $content
     * @return string
     */
    public function tagTextarea($tag, $content) {
        $id = $this->getTagAttr($tag, 'id', '');
        $name = $this->getTagAttr($tag, 'name', '');
        $className = $this->getTagAttr($tag, 'name', '');
        $value = $this->getTagAttr($tag, 'value', '');
        $impl = $this->getTagAttr($tag, 'impl', 'layui');
        $options = $this->getTagAttr($tag, 'options', '');
        $options = $this->parseJsonAttr($options);

        $parseStr = "<?php \n";
        $parseStr .= $this->_generatePhpDefinationBlock("__s_textarea_name", $name);
        if (empty($id)) {
            $parseStr .= "$" . "__s_textarea_id = 'textarea_' . time() . \common\Random::get();\n";
        } else {
            $parseStr .= $this->_generatePhpDefinationBlock("__s_textarea_id", $id);
        }
        $parseStr .= $this->_generatePhpDefinationBlock("__s_textarea_value", $value);
        $parseStr .= $this->_generatePhpDefinationBlock("__s_textarea_class", $className);
        $parseStr .= $this->_generatePhpDefinationBlock("__s_textarea_impl", $impl);
        $parseStr .= $this->_generatePhpDefinationBlock("__s_textarea_options", $options);
        $parseStr .= " ?>\n";
        $parseStr .= file_get_contents(__DIR__ . "/tpl/textarea.php");

        return $parseStr . $content;
    }

    /**
     * upload标签
     *
     * @param $tag
     * @param $content
     * @return bool|string
     */
    public function tagUpload($tag, $content) {
        $type = $this->getTagAttr($tag, "type", "file");
        $multi = $this->getTagAttr($tag, 'multi', "false");
        $result = $this->getTagAttr($tag, 'result', '');
        $callback = $this->getTagAttr($tag, 'callback', '');
        $field = $this->getTagAttr($tag, 'field', '');
        $className = $this->getTagAttr($tag, 'class', '');
        $upload = $this->getTagAttr($tag, 'upload', 'true');
        $value = $this->getTagAttr($tag, 'value', '');
        $id = $this->getTagAttr($tag, 'id', '');

        if (empty($id)) {
            $id = '"; ?><?php echo "upload_" . time() . \common\Random::get(); ?><?php echo "';
        }

        // 初始值value是一个php变量表达式
        if (startsWith($value, "$")) {
            $value = substr($value, 1);
            $value = $this->autoBuildVar($value);
            $value = '"; ?><?php echo ' . $value . '; ?><?php echo "';
        }

        $parseStr = file_get_contents(__DIR__ . "/tpl/mediaUpload.php");

        $btn = "<button class='layui-btn mediaChooseUploadBtn " . $className . "' type='button' ";
        $btn .= "data-type='" . $type . "' ";
        $btn .= "data-multi='" . $multi . "' ";
        $btn .= "data-result='" . $result . "' ";
        $btn .= "data-callback='" . $callback . "' ";
        $btn .= "data-field='" . $field . "' ";
        $btn .= "data-upload='" . $upload . "' ";
        $btn .= "data-value='" . $value . "' ";
        $btn .= "id='mediaChooseUploadBtn_" . $id . "' ";
        $btn .= ">" . $content . "</button>";

        $parseStr .= '<?php echo "' . $btn . '"; ?>';

        return $parseStr;
    }

    /**
     * 简单上传对话框
     *
     * @param $tag
     * @param $content
     * @return string
     */
    public function tagUp($tag, $content) {
        $__s_up_className = $this->getTagAttr($tag, 'class', '');
        $__s_up_success = $this->getTagAttr($tag, 'success', '');//上传成功回调
        $__s_up_id = $this->getTagAttr($tag, 'id', '');
        $__s_up_type = $this->getTagAttr($tag, "type", "file");
        $__s_up_value = $this->getTagAttr($tag, "value", "");
        $__s_up_field = $this->getTagAttr($tag, 'field', 'image');
        $__s_up_width = $this->getTagAttr($tag, 'w', '6em');
        $__s_up_height = $this->getTagAttr($tag, 'h', '6em');
        $__s_up_btn = $this->getTagAttr($tag, 'btn', 'true');
        $__s_up_maxsize = $this->getTagAttr($tag, 'maxsize', 2048);
        $__s_up_tip = $this->getTagAttr($tag, 'tip', "");

        switch ($__s_up_type) {
            case MediaTypeEnum::IMAGE:
                $__s_up_type = 'images';
                break;
            case MediaTypeEnum::VOICE:
                $__s_up_type = 'audio';
                break;
            case MediaTypeEnum::FILE:
                $__s_up_type = 'file';
                break;
        }

        $parseStr = "<?php \n";
        $parseStr .= $this->_generatePhpDefinationBlock("__s_up_className", $__s_up_className);
        $parseStr .= $this->_generatePhpDefinationBlock("__s_up_success", $__s_up_success);
        if (empty($__s_up_id)) {
            $parseStr .= "$" . "__s_up_id = 'up_' . time() . \common\Random::get();\n";
        } else {
            $parseStr .= $this->_generatePhpDefinationBlock("__s_up_id", $__s_up_id);
        }
        $parseStr .= $this->_generatePhpDefinationBlock("__s_up_type", $__s_up_type);
        $parseStr .= $this->_generatePhpDefinationBlock("__s_up_value", $__s_up_value);
        $parseStr .= $this->_generatePhpDefinationBlock("__s_up_field", $__s_up_field);
        $parseStr .= $this->_generatePhpDefinationBlock("__s_up_content", $content);
        $parseStr .= $this->_generatePhpDefinationBlock("__s_up_width", $__s_up_width);
        $parseStr .= $this->_generatePhpDefinationBlock("__s_up_height", $__s_up_height);
        $parseStr .= $this->_generatePhpDefinationBlock("__s_up_btn", $__s_up_btn);
        $parseStr .= $this->_generatePhpDefinationBlock("__s_up_maxsize", $__s_up_maxsize);
        $parseStr .= $this->_generatePhpDefinationBlock("__s_up_tip", $__s_up_tip);
        $parseStr .= " ?>\n";
        $parseStr .= file_get_contents(__DIR__ . "/tpl/simpleMediaUpload.php");

        return $parseStr;
    }

    /**
     * 生成变量定义区块
     *
     * @param $name
     * @param $instance
     * @return string
     */
    private function _generatePhpDefinationBlock($name, $instance) {
        if (!is_string($instance)) {
            return "$" . $name . " = json_decode('" . json_encode($instance) . "', true);\n";;
        }
        if (startsWith($instance, "$")) {
            $instance = substr($instance, 1);
            $instance = $this->autoBuildVar($instance);
            return "$" . $name . " = " . $instance . ";\n";
        } else {
            return "$" . $name . " = '" . $instance . "';\n";
        }
    }

    /**
     * 选择人员及部门的自定义标签
     *
     * @param $tag
     * @param $content
     * @return string
     */
    public function tagCdu($tag, $content) {
        $id = $this->getTagAttr($tag, 'id', '');
        $name = $this->getTagAttr($tag, 'name', 'deptUsers');
        $dept = $this->getTagAttr($tag, 'dept', 'true');
        $user = $this->getTagAttr($tag, 'user', 'true');
        $role = $this->getTagAttr($tag, 'role', 'false');
        $dynamic = $this->getTagAttr($tag, 'dynamic', 'false');
        $rootDept = $this->getTagAttr($tag, 'rootDept', '1');
        $value = $this->getTagAttr($tag, 'value', '[]');
        $multi = $this->getTagAttr($tag, 'multi', 'true');

        $parseStr = "<?php ";
        if (empty($id)) {
            $parseStr .= "$" . "__cdu_id = 'cdu_' . time() . \common\Random::get();;";
        } else {
            $parseStr .= $this->_generatePhpDefinationBlock("__cdu_id", $id);
        }
        $parseStr .= $this->_generatePhpDefinationBlock("__cdu_name", $name);
        $parseStr .= $this->_generatePhpDefinationBlock("__cdu_dept", $dept);
        $parseStr .= $this->_generatePhpDefinationBlock("__cdu_user", $user);
        $parseStr .= $this->_generatePhpDefinationBlock("__cdu_role", $role);
        $parseStr .= $this->_generatePhpDefinationBlock("__cdu_dynamic", $dynamic);
        $parseStr .= $this->_generatePhpDefinationBlock("__cdu_rootDept", $rootDept);
        $parseStr .= "$" . "__cdu_hint = '" . $content . "';";
        $parseStr .= $this->_generatePhpDefinationBlock("__cdu_value", $value);
        $parseStr .= $this->_generatePhpDefinationBlock("__cdu_multi", $multi);
        $parseStr .= " ?>";
        $parseStr .= file_get_contents(__DIR__ . "/tpl/chooseDeptUser.php");

        return $parseStr;
    }

}